package edu.nf.llmtest.common.component;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;

/**
 * PromptLogger
 * 作用：将每次调用大模型的 **Prompt** 与 **Output** 以 JSON 形式落盘到本地 logs 目录，
 * 方便后续审计、调试、数据分析。
 *
 * 使用方式：在任何 Service 中注入 @Autowired PromptLogger logger，
 * 调用 logger.log(prompt, output) 即可。
 *
 * 文件命名：{时间戳}.json
 * 写入位置：项目根目录 / logs / {时间戳}.json
 *
 * @author bin
 * @since 2025/9/28
 */
@Component
public class PromptLogger {

    /** 日志存放目录 */
    private static final Path DIR = Paths.get("logs");

    /** Jackson JSON 序列化器 */
    private final ObjectMapper mapper = new ObjectMapper();

    /**
     * 构造方法：启动时自动创建 logs 目录（若不存在）
     *
     * @throws IOException 创建目录失败时抛出
     */
    public PromptLogger() throws IOException {
        Files.createDirectories(DIR);
    }

    /**
     * 记录一次 LLM 调用
     *
     * @param prompt  发送给模型的提示文本
     * @param output  模型返回的原始字符串
     * @throws IOException 写入文件失败时抛出
     */
    public void log(String prompt, String output) throws IOException {
        // 封装成 Record 对象，便于序列化
        String json = mapper.writeValueAsString(new Record(prompt, output));

        // 文件名 = 当前时间戳（毫秒）.json
        String fileName = Instant.now().toEpochMilli() + ".json";

        // 写入 logs 目录
        Files.writeString(DIR.resolve(fileName), json);
    }

    /**
     * 内部记录实体，用于 Jackson 序列化
     *
     * @param prompt  提示文本
     * @param output  模型输出
     */
    private record Record(String prompt, String output) {
    }
}